package com.thfw.test.view.mq;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import scooper.cn.sc_base.SCLog;

/**
 * Created by scooper_lxx on 2017/2/16.
 */

public class MqttClientManager implements IMqttManager {

    private final static String TAG = MqttClientManager.class.getCanonicalName();
    private final static String PAHOACTION = "PahoHelper." + TAG;

    public static final int MSG_WHAT_CONNECTED = 1;
    public static final int MSG_WHAT_TOPIC = 2;
    private final static String SET_JX_STATUES="setJxStatus";
    private final static String SET_JX_Config="setJxConfig";

    private MqttAndroidClient mAndroidClient;
    private MqttConnectOptions mqttConnectOptions;
    private ConfigBean mConfigBean;

    private List<String> topicList = new ArrayList<>();
    private Handler handler;

    private ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(3);

    private boolean isConnect = false;

    public MqttClientManager(Handler handler) {
        this.handler = handler;
    }


    @Override
    public void setConfigBean(Context context, ConfigBean configBean) {

        mConfigBean = configBean;
        mqttConnectOptions = mConfigBean.buildOptions();
        try {
            mAndroidClient = new MqttAndroidClient(context, mConfigBean.getApolloUrl(), "android:" + configBean.getClientId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        receive();
    }

    @Override
    public boolean connect() {

        if (this.mConfigBean == null) {

            Log.e(TAG, "配置信息未设置，请优先设置基础参数");
            return false;

        } else {

            try {
                if(mAndroidClient != null && !isConnect()) {
                    isConnect = true;
                    mAndroidClient.connect(mqttConnectOptions, null, iMqttActionListener);
                }

            } catch (MqttException e) {
                e.printStackTrace();
                Log.e(TAG, "connect apollo lost");
                exceptionLog(e);
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
                SCLog.e(TAG, e.toString());
                SCLog.e(TAG, "connect apollo lost");
            }
            Log.e(TAG, "Apollo Connected success");
            return true;

        }
    }

    @Override
    public void disconnect() {
        try {
            isConnect = false;
            if (isConnect()) {
                mAndroidClient.disconnect();
            } else {
                Log.e(TAG, "connecte close failure");
            }
        } catch (MqttException var2) {
            Log.e(TAG, "connecte close failure");
            this.exceptionLog(var2);
        }
        Log.e(TAG, "connect close success");
    }

    public void destroy() {
        if (mAndroidClient != null) {
            disconnect();
            mAndroidClient = null;
        }
        if (handler != null) {
            handler = null;
        }
    }

    @Override
    public boolean isConnect() {
        if (mAndroidClient != null) {
            try {
                return this.mAndroidClient.isConnected();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                return false;
            }
        }
        return false;
    }

    @Override
    public boolean publish(String topic, MessageModel message) {

        boolean isretained = this.mConfigBean.getIsretained();
        String msg = message == null ? "" : message.toString();

        try {
            this.mAndroidClient.publish(topic, msg.getBytes(), this.mConfigBean.getQos(), isretained);
        } catch (MqttException var6) {
            Log.e(TAG, "send topic is" + topic + " , " + msg + " failure");
            this.exceptionLog(var6);
            var6.printStackTrace();
            return false;
        }

        Log.d(TAG, "send topic " + topic + " success");
        return true;
    }

    @Override
    public boolean subscribe(String topic) {
        if (TextUtils.isEmpty(topic)) {
            Log.e(TAG, "主题为空");
            return true;
        } else {
            try {
                this.mAndroidClient.subscribe(topic, this.mConfigBean.getQos());
                this.topicList.add(topic);
            } catch (MqttException var3) {
                Log.e(TAG, "订阅主题【" + topic + "】失败");
                this.exceptionLog(var3);
                return false;
            }

            Log.e(TAG, "订阅主题【" + topic + "】成功");
            return true;
        }
    }

    @Override
    public boolean subscribe(String[] topics) {
         if (topics.length == 0) {
            Log.e(TAG, "没有传入要订阅的主题");
            return true;
        } else {
             for (String topic : topics) {
                 if (!TextUtils.isEmpty(topic)) {
                     try {
                         this.mAndroidClient.subscribe(topic, this.mConfigBean.getQos());
                         this.topicList.add(topic);
                     } catch (MqttException var7) {
                         Log.e(TAG, "订阅主题【" + topic + "】失败");
                         this.exceptionLog(var7);
                         return false;
                     }

                     Log.e(TAG, "订阅主题【" + topic + "】成功");
                 }
             }

            return true;
        }
    }

    @Override
    public boolean unsubscribe(String[] topics) {
        if (topics.length == 0) {
            Log.e(TAG, "没有传入要注销订阅的主题");
            return true;
        } else {
            for (String topic : topics) {
                if (!TextUtils.isEmpty(topic)) {
                    try {
                        this.mAndroidClient.unsubscribe(topic);
                        this.removeSubTopic(topic);
                    } catch (MqttException var7) {
                        Log.e(TAG, "注销订阅主题【" + topic + "】失败");
                        this.exceptionLog(var7);
                        return false;
                    }

                    Log.e(TAG, "注销订阅主题【" + topic + "】成功");
                }
            }
            return true;
        }
    }

    @Override
    public boolean unsubscribe(String topic) {
        if (TextUtils.isEmpty(topic)) {
            Log.e(TAG, "topic is null");
            return false;
        } else {
            try {
                this.mAndroidClient.unsubscribe(topic);
                this.removeSubTopic(topic);
            } catch (MqttException var3) {

                Log.e(TAG, "Cancel subscription topic " + topic + " failure");
                this.exceptionLog(var3);
                return false;
            }

            Log.e(TAG, "Cancel subscription topic " + topic + " success");
            return true;
        }
    }

    @Override
    public List<String> getSubTopics() {
        return this.topicList;
    }

    private void exceptionLog(MqttException e) {
        Log.e(TAG, "reason " + e.getReasonCode());
        Log.e(TAG, "msg " + e.getMessage());
        Log.e(TAG, "loc " + e.getLocalizedMessage());
        Log.e(TAG, "cause " + e.getCause());
        Log.e(TAG, "excep " + e);
    }

    private void receive() {
        if (this.mAndroidClient == null) {
            Log.e(TAG, "apollo cannot arrived with not has connected");
        } else {

            this.mAndroidClient.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable throwable) {
                    Log.e(TAG, "losing apollo connect");
                   // mAndroidClient.close();
                    if (isConnect) {
                        reconnect();
                    }
                }

                @Override
                public void messageArrived(String s, MqttMessage message) throws Exception {
                    String data = new String(message.getPayload(), "utf-8");
                    if (handler != null) {
                        Message msg = Message.obtain();
                        msg.obj = s.charAt(0) == '/'? s:"/"+s;
                        Bundle bundle = new Bundle();
                        bundle.putString("data", data);
                        msg.setData(bundle);
                        msg.what = MSG_WHAT_TOPIC;
                        handler.sendMessage(msg);
                    }
                    SCLog.i(TAG, "receiver topic: " + s + "\tmessage: " + data + "\t\tthread:" + Thread.currentThread().getName());

                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    Log.e(TAG, "push success");
                    Intent intent = new Intent(PAHOACTION);
                    mConfigBean.getContext().sendBroadcast(intent);
                }
            });

        }
    }

    // MQTT是否连接成功
    private IMqttActionListener iMqttActionListener = new IMqttActionListener() {

        @Override
        public void onSuccess(IMqttToken arg0) {
            Log.e(TAG, "连接成功 ");
            if (mAndroidClient != null && isConnect()) {
//                subscribe(MessageManager.getTextSubscribe());
//                subscribe(MessageManager.getFileSubscribe());
//                subscribe(MessageManager.getVideoSubscribe());
//                handler.sendEmptyMessage(1);
                unsubscribe(mConfigBean.getTopic());
                subscribe(mConfigBean.getTopic());
                if (handler != null) {
                    handler.sendEmptyMessage(MSG_WHAT_CONNECTED);
                }
            }
        }

        @Override
        public void onFailure(IMqttToken arg0, Throwable arg1) {
            arg1.printStackTrace();
            Log.e(TAG, "连接失败" + arg1.toString());
            // 连接失败，重连
            threadPool.schedule(new Runnable() {
                @Override
                public void run() {
                    if (isConnect) {
                        reconnect();
                    }
                }
            }, 10000, TimeUnit.MILLISECONDS);
        }
    };

    private synchronized void reconnect() {
        if (mAndroidClient != null && !isConnect()) {
            mAndroidClient.unregisterResources();
            threadPool.schedule(new Runnable() {
                @Override
                public synchronized void run() {
                    connect();
                }
            }, 1000, TimeUnit.MILLISECONDS);
        }
    }

    private void removeSubTopic(String removeTopic) {
        if (TextUtils.isEmpty(removeTopic)) {
            Log.e(TAG, "removeTopic is not null");
        } else {
            for (int i = 0; i < this.topicList.size(); ++i) {
                if (this.topicList.get(i).equals(removeTopic)) {
                    this.topicList.remove(i);
                    --i;
                }
            }

        }
    }

    public void pushLightOprate(String type,int num ,String state){
        MessageModel messageModel =  new MessageModel(0, type, num,state);
        this.publish("/v1/local/opreateLamp", messageModel);
    }


}
